package com.test.config;

import com.test.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * @author lzy
 * @version v1.0
 * Create DateTime: 2018/11/28 9:42
 *
 * bean的生命周期:
 * bean创建--初始化--销毁的过程
 * 容器管理bean的生命周期
 * 可以自定义初始化和销毁的方法：容器在bean进行到当前生命周期的时候调用自定义的初始化和销毁方法
 *
 * 构造（对象创建）
 *     单实例：在容器启动的时候创建对象
 *     多实例：在每次获取的时候创建对象
 * 初始化：对象创建完成，并赋值好，调用初始化方法
 * 销毁：容器关闭的时候进行销毁,单实例在容器关闭的时候销毁bean，而多实例容器不会管理这个bean，容器也不会调用销毁方法，可以手动调用销毁方法
 *
 * 1.指定初始化销毁方法:通过@Bean指定init-method和destory-method
 * 2.通过让Bean实现InitializingBean(定义初始化逻辑) DisposableBean（定义销毁逻辑）
 * 3.可以使用JSR250定义的注解：
 *     @PostConstruct : 在bean创建完成并完成属性值赋值操作,来执行初始化方法
 *     @PreDestory: ：在容器销毁bean之前通知进行清理工作
 * 4.interface BeanPostProcessor ,bean的后置处理器
 * 在bean初始化前后进行处理工作：
 * postProcessBeforeInitialization:在初始化之前执行
 * postProcessAfterInitialization:在初始化之后工作
 *
 * BeanPostProcessor的原理
 * 遍历得到容器中所有的BeanPostProcessor，挨个执行BeforeInitialization
 * 一旦返回了null，跳出for循环，不会执行后续的BeanPostProcessor.postProcessAfterInitialization
 *
 * populateBean(beanName,mbd,instanceWrapper)//给bean进行属性赋值
 * initializeBean
 * {
 *     applyBeanPostProcessorsBeforeInitialization(bean, beanName);
 *     invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) //执行自定义初始化
 *     applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 * }
 *
 * Spring底层对BeanPostProcessor的使用：
 * 1.注入ioc容器，让需要使用ioc容器的类实现ApplicationContextAware接口
 * 2.bean赋值，注入其他组件，@Autowired，声明周期注解功能，@Async， xxx BeanPostProcessor等
 *
 */
@Configuration
@ComponentScan("com.test.bean")
public class MainConfigOfLifeCycle {

    @Scope("prototype")
    @Bean(initMethod = "init", destroyMethod = "destory")
    public Car car() {
        return new Car();
    }
}
